#状态模式


#一、状态模式的优点和应用场景
#优点：
#1、状态模式的优点是结构清晰，相比于if… else …简约了不少；2、封装性好，外部调用不必知道内部实现细节。

#应用场景：
#1、行为状态改变的场景。这点在各种控制器中非常常见，同时，逻辑结构为状态转移图的场景中都非常适用。

#二、状态模式的缺点
#1、在状态比较多时，子类也会非常多，不便于管理。

class LiftState:
    def open(self):
        pass

    def close(self):
        pass

    def run(self):
        pass

    def stop(self):
        pass


class OpenState(LiftState):
    def open(self):
        print ("OPEN:The door is opened...")

        return self

    def close(self):
        print ("OPEN:The door start to close...")

        print ("OPEN:The door is closed")

        return StopState()

    def run(self):
        print ("OPEN:Run Forbidden.")

        return self

    def stop(self):
        print ("OPEN:Stop Forbidden.")

        return self


class RunState(LiftState):
    def open(self):
        print ("RUN:Open Forbidden.")

        return self

    def close(self):
        print ("RUN:Close Forbidden.")

        return self

    def run(self):
        print ("RUN:The lift is running...")

        return self

    def stop(self):
        print ("RUN:The lift start to stop...")

        print ("RUN:The lift stopped...")

        return StopState()


class StopState(LiftState):
    def open(self):
        print ("STOP:The door is opening...")
        print ("STOP:The door is opened...")
        return OpenState()

    def close(self):
        print ("STOP:Close Forbidden")
        return self

    def run(self):
        print ("STOP:The lift start to run...")

        return RunState()

    def stop(self):
        print ("STOP:The lift is stopped.")

        return self


class Context:
    lift_state = ""

    def getState(self):
        return self.lift_state

    def setState(self, lift_state):
        self.lift_state = lift_state

    def open(self):
        self.setState(self.lift_state.open())

    def close(self):
        self.setState(self.lift_state.close())

    def run(self):
        self.setState(self.lift_state.run())

    def stop(self):
        self.setState(self.lift_state.stop())


if __name__ == "__main__":
    ctx = Context()
    ctx.setState(StopState())
    ctx.open()
    ctx.run()
    ctx.close()
    ctx.run()
    ctx.stop()
